﻿#include <iostream>
#include <vector>
#include <algorithm>


using namespace std;


/*
给你一个整数方阵 arr ，定义「非零偏移下降路径」为：
从 arr 数组中的每一行选择一个数字，且按顺序选出来的数字中，相邻数字不在原数组的同一列。
请你返回非零偏移下降路径数字和的最小值。

 

示例 1：
输入：arr = [[1,2,3],[4,5,6],[7,8,9]]
输出：13
解释：
所有非零偏移下降路径包括：
[1,5,9], [1,5,7], [1,6,7], [1,6,8],
[2,4,8], [2,4,9], [2,6,7], [2,6,8],
[3,4,8], [3,4,9], [3,5,7], [3,5,9]
下降路径中数字和最小的是 [1,5,7] ，所以答案是 13 。
 

提示：
1 <= arr.length == arr[i].length <= 200
-99 <= arr[i][j] <= 99

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/minimum-falling-path-sum-ii
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/


class Solution {
public:
	vector<vector<int>> dp;
	/*struct  line {
		int val;
		int x; int y;
	};*/
	//vector<struct minPerLine> v;
	int minFallingPathSum(vector<vector<int>>& matrix) {
		int m = matrix.size();  int n = matrix[0].size();
		dp = vector<vector<int>>(m,vector<int>(n));

		for (int i = 0; i < n; i++) {
			dp[0][i] = matrix[0][i];
		}

		for (int i = 1; i < m; i++) {
			for (int j = 0; j < n; j++) {
				int prevMin = 9999999;
				for (int k = 0; k < n; k++) {
					if (k != j) {
						prevMin = min(prevMin,dp[i-1][k]);
					}
				}
				dp[i][j] = prevMin + matrix[i][j];
			}
		}

		int ans = 99999999;
		for (int i = 0; i < n; i++) {
			ans = min(ans, dp[m - 1][i]);
		}

		return ans;
	}
};


//
//int main() {
//	Solution s;
//	
//	vector<vector<int>>  vv{
//		{1,2,3},
//		{4,5,6},
//		{7,8,9}
//	};
//	cout << s.minFallingPathSum(vv);
//
//	return 0;
//}
